package com.mspbots.core.attendance;

import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.mspbots.core.enums.AttendanceTypeEnum;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;

/**
 * @author billb
 */
@Log4j2
@RestController
@RequestMapping("attendances")
public class AttendancesController {

    private final AttendancesService service;

    public AttendancesController(AttendancesService service) {
        this.service = service;
    }

    @GetMapping("find-one")
    public Callable findByOne(AttendanceParams lastParams) {
        return () -> {
            List<Attendance> attendanceList = this.service.selectList(lastParams);
            return attendanceList.size() > 0 ? attendanceList.get(0) : null;
        };
    }

    @GetMapping("last")
    public Callable findByUserLast(AttendanceParams lastParams) {
        return () -> this.service.findLogLast(lastParams);
    }

    @GetMapping("all-user")
    public Callable findAllUser(AttendanceParams lastParams) {
        return () -> this.service.allUserDay(lastParams);
    }

    @GetMapping("list-for-rule")
    public Callable listForRule(AttendanceParams query) {
        Assert.notNull(query.getTenantId(), () -> "Tenant id is can not be empty or null.");
        return () -> this.service.selectList(query);
    }

    @GetMapping("page")
    public Callable page(Page<Attendance> page, AttendanceParams queryParams) {
        return () -> this.service.page(page, queryParams);
    }

    @PostMapping("save")
    public Callable save(@RequestBody AttendanceParams params) {
        return () -> this.service.save(params);
    }

    @Data
    @NoArgsConstructor
    public static class AttendanceParams {
        private Long id;
        private Long tenantId;
        private Long userId;
        private String teamsId;
        private LocalDateTime startTime;
        private LocalDateTime endTime;
        private LocalDateTime logTime;
        private AttendanceTypeEnum type;
        private String tz;
        private String tzStr;
        private Integer fromType;
        private Long departmentId;

        @Builder
        public AttendanceParams(Long tenantId, Long userId, String teamsId,
                                LocalDateTime startTime, LocalDateTime endTime, LocalDateTime logTime,
                                AttendanceTypeEnum type, String tz, String tzStr, Integer fromType) {
            this.tenantId = tenantId;
            this.userId = userId;
            this.teamsId = teamsId;
            this.startTime = startTime;
            this.endTime = endTime;
            this.logTime = logTime;
            this.type = type;
            this.tz = tz;
            this.tzStr = tzStr;
            this.fromType = fromType;
        }

        public Map<SFunction<Attendance, ?>, Object> toMap() {
            Map<SFunction<Attendance, ?>, Object> resultMap = new HashMap<>(8);
            resultMap.put(Attendance::getTenantId, this.tenantId);
            resultMap.put(Attendance::getTenantUserId, this.userId);
            resultMap.put(Attendance::getTeamsUserId, this.teamsId);
            resultMap.put(Attendance::getType, this.type);
            return resultMap;
        }

        public Map<String, Object> toStrMap() {
            Map<String, Object> resultMap = new HashMap<>(8);
            resultMap.put("attendance.tenant_id", this.tenantId);
            resultMap.put("attendance.tenant_user_id", this.userId);
            resultMap.put("attendance.teams_user_id", this.teamsId);
            resultMap.put("attendance.type", this.type);
            return resultMap;
        }
    }
}
